﻿using System.Collections.Generic;
using NHibernate;
using NHibernate.Criterion;

namespace Inovout.Repositories
{
    public abstract class BaseRepository<TModel> : BaseRepository, IRepository<TModel> where TModel : class
    {
        protected ISession OpenSession()
        {
            return SessionManager.OpenSession(); 
        }
        public virtual void Save(TModel model)
        {
            ISession session = OpenSession();
            session.SaveOrUpdate(model);
        }

        public virtual void Delete(object id)
        {
            ISession session = OpenSession();
            session.Delete(session.Load(typeof(TModel), id));
        }
        public virtual void Delete(TModel model)
        {
            ISession session = OpenSession();
            session.Delete(model);
        }

        public virtual TModel FindById(object id)
        {
            ISession session = OpenSession();
            return session.Load<TModel>(id);
        }

        protected virtual IEnumerable<TModel> Query()
        {
            return null;
        }
        //public IEnumerable<TModel> PagingQuery(int pageSize, int pageIndex, out int recordCount)
        //{
        //    recordCount = pageSize*pageIndex;
        //    return null;
        //}
        //protected PagingQuery PagingQuery(int recordCount, int pageSize, int pageIndex)
        //{
        //    return null;
        //}

        protected virtual CriteriaQuery<TModel> CreateCriteriaQuery()
        {
            ISession session = OpenSession();
            ICriteria sessionCriteria = session.CreateCriteria<TModel>();
            return new CriteriaQuery<TModel>(sessionCriteria);
        }
        public virtual IList<TModel> FindAll()
        {
            CriteriaQuery<TModel> criteriaQuery = CreateCriteriaQuery();
            return criteriaQuery.Execute();
        }

        public TModel Find(params ICriterion[] criterions)
        {
            IList<TModel> list = CreateCriteriaQuery().Where(criterions).Execute();
            if (list.Count == 0)
            {
                return null;
            }
            else if (list.Count == 1)
            {
                return list[0];
            }
            else
            {
                string identifier = string.Empty;
                foreach (var criterion in criterions)
                {
                    identifier += criterion.ToString();
                    identifier += " ";
                }
                throw new ObjectNotFoundException(identifier, typeof(TModel));
            }
        }

        public virtual IEnumerable<TModel> FindbyKeyWord(string keyWord)
        {
            if (string.IsNullOrEmpty(keyWord))
            {
                return FindAll();
            }
            string[] keyWords = keyWord.Split(' ');
            ISession session = OpenSession();

            return null;
   
        }
    }
}
